(* This file is part of IsoType.
 *
 * IsoType is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * IsoType is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with IsoType.  If not, see <http://www.gnu.org/licenses/>.
 *)

{
open Parser
exception Eof

let keywords = [
  "module", MODULE;
  "sig", SIG;
  "end", END;
  "type", TYPE;
  "val", VAL;
  "of", OF;
  "and", AND;
  "exception", EXCEPTION;
  "mutable", MUTABLE;
]
}

let tchar = ['a'-'z']

let chars =  ['a'-'z'] | '_'
let cap_chars = ['A'-'Z']
let numbers = ['0'-'9']
let apos = '\''*

let id = chars (chars | cap_chars | numbers)* apos
let cid = cap_chars (chars | cap_chars | numbers)*
let qid = (cid '.')+id

rule token = parse 
| [' ''\t''\n'] { token lexbuf }
| "(*" { comment 0 lexbuf }
| '(' { LPAREN }
| ')' { RPAREN }
| '{' { LBRACK }
| '}' { RBRACK }
| '|' { OR }
| "->" { ARROW }
| '*' { STAR }
| '=' { EQ }
| ':' { COLON }
| ';' { SEMICOLON }
| '.' { DOT }
| ',' { COMMA }
| '\''(id as s) { TVAR s }
| id as s {
    try
      List.assoc s keywords
    with
	Not_found -> ID s
  }
(* | qid as s { QID (List.rev (StringAux.split s '.')) } *)
| cid as s { CID s }
| eof { EOF }
| _ as s { prerr_endline (Printf.sprintf "*** LEXER ERROR: UNRECOGNIZED CHARACTER %c (IGNORED)" s);
	   assert false }

and comment n = parse
    "(*" { comment (n + 1) lexbuf }
| "*)" { if n = 0 then token lexbuf else comment (n - 1) lexbuf }
| eof { assert false }
| _ { comment n lexbuf }
